package model;

import model.Human;
import model.Server;
import model.game.Item;
import model.game.Player;
import model.game.Skill;
import controller.link.battle.Ask4BattleInfo;
import controller.link.EnemyTimeout;
import controller.link.battle.TurnToAttack;
import controller.link.game.YouLeveled;
import controller.link.game.YouLose;
import controller.link.game.YouWin;

public class Battle {

    private Human human1;
    private Attendant at1;
    private Human human2;
    private Attendant at2;
    private Server sv;

    public Battle(Attendant at1, Player p1, Attendant at2, Player p2, Server sv) {
        this.at1 = at1;
        human1 = new Human(p1, p2);
        this.at2 = at2;
        human2 = new Human(p2, p1);
        this.sv = sv;
    }
    
    public Player getOpponPlayer(Player pl){
        if (pl.equals(at1.getUser().getPlayer())){
            return at2.getUser().getPlayer();
        }else{
            return at1.getUser().getPlayer();
        }
    }
    public void init() {
        int velHum1 = human1.getPlayer().getAgility();
        int velHum2 = human2.getPlayer().getAgility();
        if (velHum1 > velHum2) {
            //começa com player 1
            TurnToAttack ta = new TurnToAttack(at1);
        } else if (velHum2 >= velHum1) {
            TurnToAttack ta = new TurnToAttack(at2);
            //começa com player 2;
        }

        //Calcula o mais rápido, que irá começar a batalha;
        //manda o código para o mais rápido, destravando ele,  para ele enviar uma habilidade e o trava;
        //recebe o codigo, processa o dano envia para os 2;
        //manda o codigo para o menos rapido, destravando ele, para ele enviar uma habilidade e o trava;
        //repete o laço até que um dos dois não tenha mais vida;
        //quando isso acontecer, manda uma mensagem extraordinaria dizendo que tal player é o vencedor
        //e o outro o derrotado;
    }
    public void timeout(Attendant at){
        if (at.equals(at1)) {
            EnemyTimeout et = new EnemyTimeout(at2);
        } else {
            EnemyTimeout et = new EnemyTimeout(at1);         
        }
    }
    public void useConsumable (Attendant at, String str){
        String move;
        if (at.equals(at1)){
            Item item = at1.getUser().getPlayer().findItem(str);
            item.use();
            move = at1.getUser().getName()+" used "+ item.getName();
            sendMessage(move);
            endTurn(at);            
        }else{
            Item item = at2.getUser().getPlayer().findItem(str);
            item.use();
            move = at2.getUser().getName()+" used "+ item.getName();
            sendMessage(move);
            endTurn(at);   
        }
        
    }
    public boolean isBattling(Attendant at) {
        if (at.equals(at1) || at.equals(at2)) {
            return true;
        } else {
            return false;
        }
    }
    public void move(Attendant at, Skill skill) {
        String move;
        if (at.equals(at1)) {
            move = human1.move(skill);
        } else {
            move = human2.move(skill);
        }
        sendMessage(move);
        if (!endBattle()) {
            endTurn(at);
        } else {
            sv.removeBattle(this);
            //manda msg usando whoWon and whosDeath
            YouWin yw = new YouWin(whoWon());
            YouLose yl = new YouLose(whosIsDeath());
            if(whoWon().getUser().getPlayer().addXpLeveled(whosIsDeath().getUser().getPlayer().xpToLvl())){
                YouLeveled youLeveled = new YouLeveled(sv, whoWon());
            }
            
        }
    }

    public void sendMessage(String move) {
        //Player[] players = {human1.me, human2.me};
        Ask4BattleInfo abi1 = new Ask4BattleInfo(move);
        abi1.serverUse(sv, at1);
        Ask4BattleInfo abi2 = new Ask4BattleInfo(move);
        abi2.serverUse(sv, at2);
        //Message msg = new Message(12, move);
        //at1.send(msg);
        //Player[] players2 = {human2.me, human1.me};
        //Message msg2 = new Message(12, move);
        //at2.send(msg2);
        //return to servidor and then to all clients o resultado do movimento
    }

    public void endTurn(Attendant at) {
        if (!at.equals(at1)) {
            nextTurn(at1);
        } else {
            nextTurn(at2);
        }
    }

    public void nextTurn(Attendant at) {
        //envia o codigo ao servidor para o proximo oponente;
        TurnToAttack ta = new TurnToAttack(at);
    }

    public boolean endBattle() {
        if (human1.me.getLife() <= 0 || human2.me.getLife() <= 0) {
            return true;
        } else {
            return false;
        }
    }

    public Attendant whoWon() {
        if (human1.me.getLife() > 0) {
            return at1;
        } else if (human2.me.getLife() > 0) {
            return at2;
        } else {
            return null;
        }
    }

    public Attendant whosIsDeath() {
        if (human1.me.getLife() <= 0) {
            return at1;
        } else if (human2.me.getLife() <= 0) {
            return at2;
        } else {
            return null;
        }
    }
}